package com.andova.manager;

import android.app.Application;
import android.content.Context;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import java.util.Set;

import static com.andova.manager.CacheManager.SHARED_PREFERENCE_NAME_DATA_CACHE;

/**
 * Created by Administrator on 2018-08-14.
 *
 * @author kzaxil
 * @since 0.0.3
 * @deprecated use {@link CacheManager} instead
 */
@SuppressWarnings("unused")
public class SharedPreferenceManager {
    private static volatile SharedPreferenceManager sInstance;
    private final Gson mGson = new Gson();
    private Application mApplication;

    public static SharedPreferenceManager obj() {
        if (sInstance == null) {
            synchronized (SharedPreferenceManager.class) {
                if (sInstance == null) sInstance = new SharedPreferenceManager();
            }
        }
        return sInstance;
    }

    public void initialize(@Nullable Application application) {
        mApplication = application;
    }

    public void edit(@NonNull String key, @Nullable String value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putString(key, value).apply();
    }

    public void edit(@NonNull String key, int value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putInt(key, value).apply();
    }

    public void edit(@NonNull String key, long value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putLong(key, value).apply();
    }

    public void edit(@NonNull String key, float value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putFloat(key, value).apply();
    }

    public void edit(@NonNull String key, boolean value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putBoolean(key, value).apply();
    }

    public void edit(@NonNull String key, @Nullable Set<String> value) {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putStringSet(key, value).apply();
    }

    public void clear() {
        if (mApplication == null) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().clear().apply();
    }

    public String getString(@NonNull String key) {
        return getString(key, "");
    }

    public String getString(@NonNull String key, @Nullable String defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getString(key, defValue);
    }

    @Nullable
    public Set<String> getStringSet(@NonNull String key) {
        return getStringSet(key, null);
    }

    @Nullable
    public Set<String> getStringSet(@NonNull String key, @Nullable Set<String> defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getStringSet(key, defValue);
    }

    public int getInt(@NonNull String key) {
        return getInt(key, -1);
    }

    public int getInt(@NonNull String key, int defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getInt(key, defValue);
    }

    public long getLong(@NonNull String key) {
        return getLong(key, -1L);
    }

    public long getLong(@NonNull String key, long defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getLong(key, defValue);
    }

    public float getFloat(@NonNull String key) {
        return getFloat(key, -1);
    }

    public float getFloat(@NonNull String key, float defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getFloat(key, defValue);
    }

    public boolean getBoolean(@NonNull String key) {
        return getBoolean(key, false);
    }

    public boolean getBoolean(@NonNull String key, boolean defValue) {
        if (mApplication == null) return defValue;
        return mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getBoolean(key, defValue);
    }

    public void editWhatI(@NonNull String key, int what) {
        IntA a = getIntA(key);
        if (a == null || a.getWhat() == what) return;
        a.setWhat(what);
        editIntA(key, a);
    }

    public void editWhatL(@NonNull String key, int what) {
        LongA a = getLongA(key);
        if (a == null || a.getWhat() == what) return;
        a.setWhat(what);
        editLongA(key, a);
    }

    public void editWhatF(@NonNull String key, int what) {
        FloatA a = getFloatA(key);
        if (a == null || a.getWhat() == what) return;
        a.setWhat(what);
        editFloatA(key, a);
    }

    public void editWhatS(@NonNull String key, int what) {
        StringA a = getStringA(key);
        if (a == null || a.getWhat() == what) return;
        a.setWhat(what);
        editStringA(key, a);
    }

    public void editWhatB(@NonNull String key, int what) {
        BooleanA a = getBooleanA(key);
        if (a == null || a.getWhat() == what) return;
        a.setWhat(what);
        editBooleanA(key, a);
    }

    public void editIntA(@NonNull String key, int value) {
        editIntA(key, value, 1, 0, 0, null);
    }

    public void editIntA(@NonNull String key, int value, int what) {
        editIntA(key, value, what, 0, 0, null);
    }

    public void editIntA(@NonNull String key, int value, int what, int arg1, int arg2, @Nullable Object obj) {
        editIntA(key, new IntA(value, what, arg1, arg2, obj));
    }

    public void editIntA(@NonNull String key, @NonNull IntA value) {
        editJson(key, value);
    }

    @Nullable
    public IntA getIntA(@NonNull String key) {
        return getJson(key, IntA.class);
    }

    public IntA getIntA(@NonNull String key, int defValue) {
        IntA a = getIntA(key);
        return a == null ? new IntA(defValue, 0, 0, 0, null) : a;
    }

    public void editLongA(@NonNull String key, long value) {
        editLongA(key, value, 1, 0, 0, null);
    }

    public void editLongA(@NonNull String key, long value, int what) {
        editLongA(key, value, what, 0, 0, null);
    }

    public void editLongA(@NonNull String key, long value, int what, int arg1, int arg2, @Nullable Object obj) {
        editLongA(key, new LongA(value, what, arg1, arg2, obj));
    }

    public void editLongA(@NonNull String key, @NonNull LongA value) {
        editJson(key, value);
    }

    @Nullable
    public LongA getLongA(@NonNull String key) {
        return getJson(key, LongA.class);
    }

    public LongA getLongA(@NonNull String key, long defValue) {
        LongA a = getLongA(key);
        return a == null ? new LongA(defValue, 0, 0, 0, null) : a;
    }

    public void editFloatA(@NonNull String key, float value) {
        editFloatA(key, value, 1, 0, 0, null);
    }

    public void editFloatA(@NonNull String key, float value, int what) {
        editFloatA(key, value, what, 0, 0, null);
    }

    public void editFloatA(@NonNull String key, float value, int what, int arg1, int arg2, @Nullable Object obj) {
        editFloatA(key, new FloatA(value, what, arg1, arg2, obj));
    }

    public void editFloatA(@NonNull String key, @NonNull FloatA value) {
        editJson(key, value);
    }

    @Nullable
    public FloatA getFloatA(@NonNull String key) {
        return getJson(key, FloatA.class);
    }

    public FloatA getFloatA(@NonNull String key, float defValue) {
        FloatA a = getFloatA(key);
        return a == null ? new FloatA(defValue, 0, 0, 0, null) : a;
    }

    public void editStringA(@NonNull String key, @NonNull String value) {
        editStringA(key, value, 1, 0, 0, null);
    }

    public void editStringA(@NonNull String key, @NonNull String value, int what) {
        editStringA(key, value, what, 0, 0, null);
    }

    public void editStringA(@NonNull String key, @NonNull String value, int what, int arg1, int arg2, @Nullable Object obj) {
        editStringA(key, new StringA(value, what, arg1, arg2, obj));
    }

    public void editStringA(@NonNull String key, @NonNull StringA value) {
        editJson(key, value);
    }

    @Nullable
    public StringA getStringA(@NonNull String key) {
        return getJson(key, StringA.class);
    }

    public StringA getStringA(@NonNull String key, @NonNull String defValue) {
        StringA a = getStringA(key);
        return a == null ? new StringA(defValue, 0, 0, 0, null) : a;
    }

    public void editBooleanA(@NonNull String key, boolean value) {
        editBooleanA(key, value, 1, 0, 0, null);
    }

    public void editBooleanA(@NonNull String key, boolean value, int what) {
        editBooleanA(key, value, what, 0, 0, null);
    }

    public void editBooleanA(@NonNull String key, boolean value, int what, int arg1, int arg2, @Nullable Object obj) {
        editJson(key, new BooleanA(value, what, arg1, arg2, obj));
    }

    public void editBooleanA(@NonNull String key, @NonNull BooleanA value) {
        editJson(key, value);
    }

    @Nullable
    public BooleanA getBooleanA(@NonNull String key) {
        return getJson(key, BooleanA.class);
    }

    public BooleanA getBooleanA(@NonNull String key, boolean defValue) {
        BooleanA a = getBooleanA(key);
        return a == null ? new BooleanA(defValue, 0, 0, 0, null) : a;
    }

    public void editJson(@NonNull String key, @Nullable Object value) {
        if (mApplication == null) return;
        String data = mGson.toJson(value);
        if (TextUtils.isEmpty(data)) return;
        mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .edit().putString(key, data).apply();
    }

    @Nullable
    public <T> T getJson(@NonNull String key, @NonNull Class<T> model) {
        if (mApplication == null) return null;
        String data = mApplication.getSharedPreferences(SHARED_PREFERENCE_NAME_DATA_CACHE, Context.MODE_PRIVATE)
                .getString(key, "");
        try {
            return mGson.fromJson(data, model);
        } catch (JsonSyntaxException | NullPointerException e) {
            return null;
        }
    }
}
